import { getClientPos, preventDefault, haveToWindow } from '@y.dsh/utils/lib/utils'
import { findParentNode, getStyleValue } from '@y.dsh/utils/lib/dom'
import { Pos } from '../'

let start: any = null;
let move: any = null;

// 拖动事件
function handleMove(e: TouchEvent | MouseEvent, pos: Pos, button: HTMLElement) {
  preventDefault(e); // 拖动时组织默认事件
  const { clientX, clientY } = getClientPos(e);
  const { posX, posY, width, height } = pos;

  // 限制移动范围 只能在屏幕内
  let left = clientX - posX;
  if (left < 0) {
    left = 0;
  } else if (left > document.documentElement.clientWidth - width) {
    left = document.documentElement.clientWidth - width;
  }
  let top = clientY - posY;
  if (top < 0) {
    top = 0;
  } else if (top > document.documentElement.clientHeight - height) {
    top = document.documentElement.clientHeight - height;
  }

  // 设置位置
  button.style.position = 'fixed';
  button.style.left = `${left}px`;
  button.style.top = `${top}px`;
  button.style.marginTop = '0px';
}

// 取消事件
function handleEnd() {
  // 解绑各个时间
  if (haveToWindow()) {
    window.removeEventListener('mousemove', move);
    window.removeEventListener('mouseup', handleEnd);

    window.removeEventListener('touchmove', move);
    window.removeEventListener('touchend', handleEnd);
    window.removeEventListener('touchcancel', handleEnd);
  }
}

// 按下事件
function handleStart(
  e: TouchEvent | MouseEvent,
  childrenNotAllowDown: React.MutableRefObject<boolean>,
  eventOptions: false | { passive: boolean; }
) {
  preventDefault(e); // 按下的时候阻止默认事件
  const { clientX, clientY } = getClientPos(e);
  const button = findParentNode(e.target as HTMLElement, 'easy-scroll-side-button-drag'); // 判断当前元素是不是抖动状态
  if (button) {
    // 按下的抖动元素
    const buttonRect = getStyleValue(button);
    if (buttonRect) {
      const pos = {
        posX: clientX - buttonRect.left,
        posY: clientY - buttonRect.top,
        width: buttonRect.width,
        height: buttonRect.height
      };
      move = function (event: TouchEvent | MouseEvent) {
        handleMove(event, pos, button);
      }
    }
    // 按下的时候再次绑定事件
    if (haveToWindow()) {
      window.addEventListener('mousemove', move);
      window.addEventListener('mouseup', handleEnd);

      // 移动端事件
      window.addEventListener('touchmove', move, eventOptions);
      window.addEventListener('touchend', handleEnd);
      window.addEventListener('touchcancel', handleEnd);
    }
  } else { // 如果不是抖动元素 则进入
    childrenNotAllowDown.current = false; // ScrollView重置为可操作
    // 所有的抖动元素都取消抖动
    const drags = document.querySelectorAll('.easy-scroll-side-button-drag');
    for (let i = 0; i < drags.length; i += 1) {
      drags[i].classList.remove('easy-scroll-side-button-drag');
    }
    // 删除事件
    if (haveToWindow()) {
      window.removeEventListener('mousedown', start);
      window.removeEventListener('touchstart', start);
    }
  }
}

// 长按事件
function longPressButton(
  e: TouchEvent | MouseEvent,
  childrenNotAllowDown: React.MutableRefObject<boolean>,
  eventOptions: false | { passive: boolean; }
): void {
  // 获取位置信息
  const { clientX, clientY } = getClientPos(e);

  const button = findParentNode(e.target as HTMLElement, 'easy-scroll-side-button'); // 查找到按钮节点
  if (button && !button.classList.contains('easy-scroll-side-button-drag')) { // 如果找到了 看看是不是已经在抖动状态
    const buttonRect = getStyleValue(button); // 不在就往下进行
    if (buttonRect) {
      // showToast({
      //   title: '可以拖动了~',
      //   icon: 'none',
      //   duration: 1000
      // });

      childrenNotAllowDown.current = true; // 如果触发了长按事件 则禁用下拉刷新

      button.classList.add('easy-scroll-side-button-drag'); // 修改为抖动状态

      // 按钮当前位置
      const pos = {
        posX: clientX - buttonRect.left,
        posY: clientY - buttonRect.top,
        width: buttonRect.width,
        height: buttonRect.height
      };

      start = function (event: TouchEvent | MouseEvent) { // 按下函数
        handleStart(event, childrenNotAllowDown, eventOptions);
      }
      move = function (event: TouchEvent | MouseEvent) { // 移动函数
        handleMove(event, pos, button);
      }

      // PC端事件
      if (haveToWindow()) {
        window.addEventListener('mousedown', start);
        window.addEventListener('mousemove', move);
        window.addEventListener('mouseup', handleEnd);

        // 移动端事件
        window.addEventListener('touchstart', start, eventOptions);
        window.addEventListener('touchmove', move, eventOptions);
        window.addEventListener('touchend', handleEnd);
        window.addEventListener('touchcancel', handleEnd);
      }
    }
  }
}

export default longPressButton
